package com.example.sangong.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.sangong.dao.SgLogDao;
import com.example.sangong.entity.SgLog;
import com.example.sangong.myenum.DeleteFlagEnum;
import com.example.sangong.req.log.LogStaticsQueryReq;
import com.example.sangong.resp.LogStaticsRsp;
import com.example.sangong.service.SgLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SgLogServiceImpl extends ServiceImpl<SgLogDao, SgLog> implements SgLogService {
    @Autowired
    private KafkaTemplate<Object, Object> template;
    @Resource
    private SgLogDao sgLogDao;

    private static String systemName;

    @PostConstruct
    public void initSystemName(){
        systemName = IdUtil.fastUUID();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addLog(SgLog sgLog) {
        log.info("开始保存接口操作日志:{}", sgLog);
        sgLogDao.insert(sgLog);
    }

    /**
     * 把CompletableFuture使用上，通过多次线程查询，然后组装最终结果
     *
     * @param req
     * @return
     */

    @Override
    public List<LogStaticsRsp> getLogStatics(LogStaticsQueryReq req) {
        CompletableFuture<List<LogStaticsRsp>> feature = CompletableFuture.supplyAsync(() -> getSgLogUrls()).thenApply(sgLogs -> getLogStaticsUseCf(sgLogs));
        return feature.join();
    }

    @Override
    public String getSystemName() {
        return systemName+"：哇哈哈";
    }

    /**
     * 采用CompletableFeature异步查询结果，并将多个线程查询的结果组装起来
     *
     * @param sgLogs
     * @return
     */
    private List<LogStaticsRsp> getLogStaticsUseCf(List<SgLog> sgLogs) {
        List<CompletableFuture<LogStaticsRsp>> queryList = new ArrayList<>();
        for (SgLog sgLog : sgLogs) {
            queryList.add(CompletableFuture.supplyAsync(() -> getUrlStatics(sgLog)));
        }
        List<LogStaticsRsp> collect = queryList.stream().map(CompletableFuture::join).collect(Collectors.toList());
        collect.sort((o1, o2) -> o2.getCount().compareTo(o1.getCount()));
        return collect;
    }

    private List<SgLog> getSgLogUrls() {
        QueryWrapper<SgLog> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<SgLog> sgLogLambdaQueryWrapper = queryWrapper.select("DISTINCT URL,REMARK").lambda().eq(SgLog::getDeleteFlag, DeleteFlagEnum.EFFECTIVE.getCode());
        List<SgLog> sgLogs = sgLogDao.selectList(sgLogLambdaQueryWrapper);
        return sgLogs;
    }

    private LogStaticsRsp getUrlStatics(SgLog sgLog) {
        String url = sgLog.getUrl();
        String remark = sgLog.getRemark();
        LambdaQueryWrapper<SgLog> query = new LambdaQueryWrapper<>();
        query.eq(SgLog::getDeleteFlag, DeleteFlagEnum.EFFECTIVE.getCode());
        query.eq(SgLog::getUrl, url);
        Integer count = sgLogDao.selectCount(query);
        LogStaticsRsp data = new LogStaticsRsp();
        data.setUrl(url);
        data.setRemark(remark);
        data.setCount(count);
        return data;
    }
}
